package com.ctyon.watchmanager.util;

import android.util.Log;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.ctyon.common.event.UpdateCover;
import com.ctyon.watchmanager.BasicApp;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import static com.ctyon.watchmanager.config.OssConfig.accessKeyId;
import static com.ctyon.watchmanager.config.OssConfig.accessKeySecret;
import static com.ctyon.watchmanager.config.OssConfig.apk;
import static com.ctyon.watchmanager.config.OssConfig.bucketName;
import static com.ctyon.watchmanager.config.OssConfig.endpoint;
import static com.ctyon.watchmanager.config.OssConfig.picture;

/**
 * CreateDate：19-7-26 on 上午10:59
 * Describe:
 * Coder: lee
 */
public class OssUtil {

    private OSS oss;
    private ProgressCallback progressCallback;

    public OssUtil() {
        //OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider("<StsToken.AccessKeyId>", "<StsToken.SecretKeyId>", "<StsToken.SecurityToken>");
        //这个初始化安全性没有Sts安全，如需要很高安全性建议用OSSStsTokenCredentialProvider创建（上一行创建方式）多出的参数SecurityToken为临时授权参数
        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(8); // 最大并发请求数，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次

        // oss为全局变量，endpoint是一个OSS区域地址
        oss = new OSSClient(BasicApp.getInstance().getApplicationContext(), endpoint, credentialProvider, conf);

    }

    private static class OssHolder {
        private static final OssUtil INSTANCE = new OssUtil();
    }

    public static OssUtil getOssInstance() {
        return OssUtil.OssHolder.INSTANCE;
    }

    public void setProgressCallback(ProgressCallback progressCallback) {
        this.progressCallback = progressCallback;
    }

    public interface ProgressCallback {
        void onProgressCallback(double progress);
    }

    public interface DownloadCallback {
        void onDownloadCallback(String path);
    }

    public void uploadPicture(String path) {

        String objectKey = picture + BasicApp.getInstance().getManager().getPhoneNumber() + ".png";
        Log.d("OssUtil", "objectKey = " + objectKey);

        // 构造上传请求。
        PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, path);

        // 异步上传时可以设置进度回调。
        put.setProgressCallback((request, currentSize, totalSize) -> {
            Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
            if (null != progressCallback) {
                double progress = currentSize * 1.0 / totalSize * 100.f;
                progressCallback.onProgressCallback(progress);
            }
        });

        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Log.d("PutObject", "UploadSuccess");
                Log.d("ETag", result.getETag());
                Log.d("RequestId", result.getRequestId());

                BasicApp.getInstance().getManager().setImg(path);

                Log.d("OssUtil", "post success event");
                EventBus.getDefault().post(new UpdateCover());
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常。
                if (clientExcepion != null) {
                    // 本地异常，如网络异常等。
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常。
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                }
            }
        });
    }

    public void downloadApk(String apkName, DownloadCallback downloadCallback) throws Exception {
        // download object to file
        String objectKey = apk + apkName + ".apk";
        GetObjectRequest get = new GetObjectRequest(bucketName, objectKey);
        //设置下载进度回调
        get.setProgressListener((request, currentSize, totalSize) -> {
                    OSSLog.logDebug("getobj_progress: " + currentSize + "  total_size: " + totalSize, false);
                }
        );
        OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                Log.e("OssUtil", "--onSuccess--");
                // 请求成功
                InputStream inputStream = null;
                FileOutputStream fileOutputStream = null;
                
                byte[] buffer = new byte[1024];
                int len;
                boolean b = false;
                File file = null;
                try {
                    file = new File(DirectoryUtils.getDownFileDir(), apkName + ".apk");
                    if (file.exists()){
                        if (file.length() == result.getContentLength()){
                            b = true;
                            return;
                        } else {
                            file.delete();
                        }
                    }
                    file.createNewFile();
                    Log.e("OssUtil", "path ： " + file.getPath());
                    inputStream = result.getObjectContent();
                    fileOutputStream = new FileOutputStream(file);
                    while ((len = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    Log.e("OssUtil", "finally");
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fileOutputStream != null) {
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (b && null != downloadCallback){
                        downloadCallback.onDownloadCallback(file.getPath());
                    }
                }

            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                }
            }
        });

    }

    public void ossCancel() {
        //task.cancel(); // 可以取消任务。
        // task.waitUntilFinished(); // 等待任务完成。
    }

}
